<template>
  <form-dialog
    :visible="visible"
    :title="title"
    @handleClose="handleClose"
  >
    <template v-slot:content style="text-align:center;">
      <div style="text-align:center;margin-bottom:-10px">
        <div>
          <el-upload
            v-loading="loading"
            class="upload-demo"
            drag
            action=""
            multiple
            :file-list="fileList"
            ref="uploader"
            :before-upload="beforeChange"
            :on-success="handleSuccess"
            :on-change="(file, fileList) => { handleChange(file, fileList);}"
            :auto-upload="false"
            :http-request="uploadSectionFile"
            accept=".exe, .bin"
            >
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">{{ $t('clientVersionManage.uploadVersion1') }}<em>{{ $t('clientVersionManage.uploadVersion2') }}</em>
              <div style="margin-top:15px;color: rgb(212, 146, 146);">{{ $t('clientVersionManage.uploadVersion3') }}</div>
            </div>
          </el-upload>
          <el-progress v-if="progress.isShow" :percentage="progress.percentage" :color="progress.customColor"></el-progress>
        </div>
      </div>
    </template>
    <template v-slot:footer>
      <el-button @click="handleClose">{{ $t('common.cancel') }}</el-button>
      <el-button type="primary" @click="submitF" :loading="loading">{{ $t('common.confirm') }}</el-button>
    </template>
  </form-dialog>
</template>
<script lang="ts">
import Vue from 'vue'
import sparkMd5 from 'spark-md5'
import FormDialog from '../../../components/Dialog/formDialog.vue';
import axios from 'axios';
export default Vue.extend({
  components: { FormDialog },
  props: {
    versionUploadMethod: {
      type: Function,
      default() {
        return () => Promise.resolve();
      }
    }
  },
  data() {
    return {
      loading: false,
      fileList: [],
      settings: {
        distribute_interval: 600,
        upload_size_limit: 800
      },
      // 进度条信息
      progress: {
        percentage: 0,
        customColor: "#409eff",
        percent: 0,
        isShow: false
      },
      source: null,
      visible: false,
      title: "",
      tip: "",
      message: "",
    }
  },
  methods: {
    init({
      title,
    }: any) {
      (this as any).fileList = [];
      (this as any).progress.percent = 0;
      (this as any).progress.percentage = 0;
      (this as any).progress.isShow = false;
      (this as any).title = title;
      (this as any).visible = true;
    },
    // 上传文件前改变钩子
    beforeChange(file: any) {
      if(file.type != 'application/x-msdownload' && file.type != 'application/octet-stream' && file.type !='application/macbinary'){
        this.$message.warning((this as any).$t('clientVersionManage.uploadExeTips'))
        return false;
      }
      const isLt300M = file.size / 1024 / 1024 < this.settings.upload_size_limit;
      if (!isLt300M) {
        this.$message({
          message: (this as any).$t('clientVersionManage.fileSizeLimit') + this.settings.upload_size_limit + 'MB!',
          type: 'warning'
        });
        return false;
      }
    },

    handleSuccess(res: any, file: any, fileList: any) {
      console.log(res);
    },

    handleChange(file: any, fileList: string|any[]) {
      if (fileList.length > 0) {
        (this.fileList as any) = [fileList[fileList.length - 1]];
      }
    },

    uploadSectionFile(file: any) {
      this.loading = true;
      this.fileSlice(file.file).then((res: any) => {
        let i = 0;
        let flag = 0;
        const cancelToken = axios.CancelToken;
        (this.source as any) = cancelToken.source();
        const that = this as any;
        this.progress.isShow = true;
        function uploadfile() {
          const headers = {
            "Version-Md5": res.md5,
            "Version-Size": file.file.size,
            "Version-Start-Transport": flag === 0 ? "true" : "false"
          };
          flag = 1;
          that.$pandaApi.apiUploadClientVersion(file.file.name, res.data[i], that.source.token, headers).then((res2: any) => {
            i++;
            if (res2.status === 208) {
              that.$message({
                message: (that as any).$t("clientVersionManage.versionExist") as string,
                type: 'error'
              });
              that.loading = false;
              that.progress.isShow = false;
              return 0;
            } else if (res2.status === 202) {
              that.progress.percentage = Math.floor(i * that.progress.percent);
              if (i < res.data.length) {
                uploadfile();
              }
            } else {
              that.progress.percentage = 100;
              that.$message({
                message: (that as any).$t("clientVersionManage.uploadSuccess").toString(),
                type: 'success'
              });
              (that as any).loading = false;
              (that as any).visible = false;
              (that as any).versionUploadMethod();
              return 0;
            }
          }).catch((err: any) => {
            that.loading = false;
            // console.log(err.status)
            if (axios.isCancel(err)) {
              that.$message({
                message: (that as any).$t("clientVersionManage.cancelUpload") as string,
                type: 'warning'
              });
            } else if(err.status != 204) {
              that.$message({
                message: (that as any).$t("clientVersionManage.uploadFail") as string,
                type: 'error'
              });
            }
            return 0;
          });
        }
        uploadfile();
      }).catch(() => {
        this.loading = false;
        this.progress.isShow = false;
        this.$message({
          message: (this as any).$t("clientVersionManage.uploadFail") as string,
          type: 'error'
        });
      });
    },

    // 文件分片
    fileSlice(file: any) {
      return new Promise((resolve, reject) => {
        const blobSlice = File.prototype.slice || (File.prototype as any).mozSlice || (File.prototype as any).webkitSlice;
        const chunkSize = 20971520; // 每片20M
        const chunks = Math.ceil(file.size / chunkSize);
        this.progress.percent = 100 / chunks;
        let currentChunk = 0;
        const spark = new sparkMd5.ArrayBuffer();
        const fileReader = new FileReader();
        const fileChunk: any = [];
        while (currentChunk < chunks) {
          const start = currentChunk * chunkSize;
          const end = ((start + chunkSize) >= file.size ? file.size : start + chunkSize);
          fileChunk.push(file.slice(start, end));
          currentChunk++;
        }

        function loadNext() {
          const start = 0;
          const end = file.size;
          fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
        }

        fileReader.onload = (e: any) => {
          spark.append(e.target.result);
          const md5 = spark.end();
          resolve({ data: fileChunk, md5: md5 });
        };
        fileReader.onerror = () => {
          reject(new Error());
        };
        loadNext();
      });
    },

    submitF() {
      (this as any).$refs['uploader'].submit()
    },

    handleClose() {
      if ((this as any).source) {
        (this as any).source.cancel("取消上传！");
      }
      (this as any).visible = false;
      (this as any).loading = false;
    },
  }
})
</script>
<style lang="scss" scoped>

</style>
